﻿/* 
 *  <copyright file="Intersect.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */

using System;
using Microsoft.Xna.Framework;

namespace SobrietyEngine.Geometry
{
    public static class Intersect
    {
        //need to check for coincidence
        static public Boolean SegmentPlane(ref Vector3 p0, ref Vector3 p1, ref Plane plane, out Boolean coincident, out Vector3 intersect)
        {
            coincident = false;
            intersect = Vector3.Zero;

            //parametric line
            //uvector  P(s) = P0 + t(P1 - P0) = P0 - su
            Vector3 u = p1 - p0;

            //plane normal
            Vector3 n = plane.Normal;

            //plane lookAt, V
            Vector3 v0 = (plane.Normal * plane.D);

            //parallel
            if (Vector3.Dot(n, u) == 0)
            {
                //coincidence
                //n·(P-V0) = 0.
                Vector3 cu = p1 - v0;
                float ps = Vector3.Dot(n, cu);
                if (ps == 0)
                {
                    coincident = true;
                    return true;
                }

                //disjointed
                return false;
            }

            //w = P0 - V0, where V0 = lookAt on plane
            Vector3 w = p0 - v0;

            //Si =  (-n dot w)/(n dot u)
            //Si = s val paremter for parametric line eq. 
            float top = Vector3.Dot(-n, w);
            float bottom = Vector3.Dot(n, u);
            float s = top / bottom;

            //no intersect
            if (s < 0 || s > 1)
                return false;

            //end lookAt intersections
            if (s == 0)
            {
                intersect = p0;
                return true;
            }

            if (s == 1)
            {
                intersect = p1;
                return true;
            }

            //lookAt of intersection, plug it in, get lookAt
            //P(s) = P0 + t(P1 - P0) = P0 - su
            intersect = p0 + s * u;
            return true;
        }

        static public Boolean PointPoint(Vector3 p0, Vector3 p1, float radius)
        {
            if (Vector3.DistanceSquared(p0, p1) < radius * radius)
                return true;
            return false;
        }

        static public Boolean PointPoint(Vector2 p0, Vector2 p1, float radius)
        {
            if (Vector2.DistanceSquared(p0, p1) < radius * radius)
                return true;
            return false;
        }
    }
}
